package com.bossly.contactsflag.activities;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.app.ListActivity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ListView;
import android.widget.QuickContactBadge;
import android.widget.TextView;

import com.bossly.contactsflag.R;

public class ContactsFlagActivity extends ListActivity {

	private static final String CONTACT_DATA = "contactData";

	protected static final int PICK_CONTACT = 1;

	private QuickContactBadge mbadge;
	private TextView mtext;

	private Uri _contactData;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.main);

		mbadge = (QuickContactBadge) findViewById(R.id.quickContact);
		mtext = (TextView) findViewById(android.R.id.text1);

		findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// request for contact select activity
				Intent intent = new Intent(Intent.ACTION_PICK,
						ContactsContract.Contacts.CONTENT_URI);
				startActivityForResult(intent, PICK_CONTACT);
			}
		});

		if (savedInstanceState != null) {
			_contactData = savedInstanceState.getParcelable(CONTACT_DATA);

			if (_contactData != null) {
				loadContact(_contactData);
			}
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		// TODO Auto-generated method stub
		super.onSaveInstanceState(outState);

		outState.putParcelable(CONTACT_DATA, _contactData);
	}

	@Override
	public void onActivityResult(int reqCode, int resultCode, Intent data) {
		super.onActivityResult(reqCode, resultCode, data);

		switch (reqCode) {
		case (PICK_CONTACT):
			if (resultCode == Activity.RESULT_OK) {
				Uri contactData = data.getData();
				_contactData = contactData;
				loadContact(contactData);
			}
			break;
		}
	}

	private void loadContact(Uri contactData) {
		Cursor c = managedQuery(contactData, null, null, null, null);

		if (c.moveToFirst()) {
			long contactid = c.getLong(c
					.getColumnIndexOrThrow(ContactsContract.Contacts._ID));

			Cursor cur = getContacts(contactid);

			// update contact info
			mtext.setText(c.getString(c
					.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));

			Uri contactPhotoUri = ContentUris.withAppendedId(
					ContactsContract.Contacts.CONTENT_URI, contactid);

			InputStream photoDataStream = Contacts.openContactPhotoInputStream(
					getContentResolver(), contactPhotoUri); // <-- always null

			Bitmap photo = null;

			if (photoDataStream != null) {
				photo = BitmapFactory.decodeStream(photoDataStream);
			}

			mbadge.assignContactUri(contactPhotoUri);
			mbadge.setMode(ContactsContract.QuickContact.MODE_LARGE);
			mbadge.setImageBitmap(photo);

			ContactsAdapter adapter = new ContactsAdapter(this, cur,
					(int) contactid);
			setListAdapter(adapter);
		}
	}

	/**
	 * Obtains the contact list for the currently selected account.
	 * 
	 * @return A cursor for for accessing the contact list.
	 */
	private Cursor getContacts(long contactId) {

		Cursor c = getContentResolver().query(RawContacts.CONTENT_URI, null,
				RawContacts.CONTACT_ID + "=?",
				new String[] { String.valueOf(contactId) }, null);

		return c;
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {

		// show dialog with selection flag
		final ContactTag contact = (ContactTag) v.getTag();

		if (contact.isContactType) {

		} else {
			Builder builder = new Builder(this);

			builder.setTitle(R.string.dialog_title);
			builder.setMessage(R.string.dialog_body);
			builder.setPositiveButton(android.R.string.yes,
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							long rawContactId = getRawContact(contact.contactId);
							setContactPhoto(getContentResolver(),
									contact.photo, rawContactId);
						}
					});

			builder.setNeutralButton(R.string.add_ua_flag,
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
							Bitmap photo = contact.photo;
							Bitmap flag = BitmapFactory.decodeResource(
									getResources(), R.drawable.flag);

							long rawContactId = getRawContact(contact.contactId);

							photo = addFlagToPhoto(photo, flag);

							setContactPhoto(getContentResolver(), photo,
									rawContactId);
						}
					});

			builder.setNegativeButton(android.R.string.cancel, null);
			builder.show();
		}

		super.onListItemClick(l, v, position, id);
	}

	public long getRawContact(long contactId) {

		String accountType = "com.bossly.contactflag.contact";
		String accountName = "contactflag.local";
		long rawContactId = -1;

		String where = RawContacts.CONTACT_ID + " = " + contactId + " AND "
				+ RawContacts.ACCOUNT_TYPE + "=='" + accountType + "'";

		ContentResolver c = getContentResolver();
		Cursor cursor = c.query(RawContacts.CONTENT_URI, null, where, null,
				null);
		int idIdx = cursor.getColumnIndexOrThrow(Data._ID);

		// get exist raw contact
		if (cursor.moveToFirst()) {
			rawContactId = cursor.getInt(idIdx);
		}
		// add raw contact
		else {
			ContentValues values = new ContentValues();

			values.put(RawContacts.ACCOUNT_TYPE, accountType);
			values.put(RawContacts.ACCOUNT_NAME, accountName);

			Uri rawContactUri = getContentResolver().insert(
					RawContacts.CONTENT_URI, values);

			rawContactId = ContentUris.parseId(rawContactUri);

			where = Contacts._ID + " = " + contactId;

			Cursor cr = c.query(Contacts.CONTENT_URI, null, where, null, null);
			idIdx = cr
					.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);

			// get exist raw contact
			if (cr.moveToFirst()) {
				values.clear();
				values.put(Data.RAW_CONTACT_ID, rawContactId);
				values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
				values.put(StructuredName.DISPLAY_NAME, cr.getString(idIdx));
				getContentResolver().insert(Data.CONTENT_URI, values);
			}

			cr.close();
		}

		cursor.close();

		return rawContactId;
	}

	public Cursor getSuggestions(long contactId) {
		Uri suggestionsUri = Contacts.CONTENT_URI.buildUpon()
				.appendEncodedPath(String.valueOf(contactId))
				.appendPath(Contacts.AggregationSuggestions.CONTENT_DIRECTORY)
				.appendQueryParameter("limit", "3").build();

		Cursor cursor = getContentResolver().query(
				suggestionsUri,
				new String[] { Contacts.DISPLAY_NAME, Contacts._ID,
						Contacts.LOOKUP_KEY }, null, null, null);
		return cursor;
	}

	public void setContactPhoto(ContentResolver c, Bitmap photo, long personId) {

		if (photo == null) {

			Builder builder = new Builder(this);
			builder.setMessage(R.string.no_photo);
			builder.setNegativeButton(android.R.string.ok, null);
			builder.show();

			return;
		}

		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
		byte[] bytes = stream.toByteArray();

		int photoRow = -1;

		String where = Data.RAW_CONTACT_ID + " = " + personId + " AND "
				+ Data.MIMETYPE + "=='" + Photo.CONTENT_ITEM_TYPE + "'";

		Cursor cursor = c.query(Data.CONTENT_URI, null, where, null, null);
		int idIdx = cursor.getColumnIndexOrThrow(Data._ID);
		if (cursor.moveToFirst()) {
			photoRow = cursor.getInt(idIdx);
		}

		cursor.close();

		ContentValues values = new ContentValues();
		values.put(Data.RAW_CONTACT_ID, personId);
		values.put(Data.IS_SUPER_PRIMARY, 1);
		values.put(Photo.PHOTO, bytes);
		values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);

		if (photoRow >= 0) {
			int updated = c.update(Data.CONTENT_URI, values, Data._ID + " = "
					+ photoRow, null);

			if (updated > 0) {
				mbadge.setImageBitmap(photo);
			}
		} else {
			c.insert(Data.CONTENT_URI, values);
			mbadge.setImageBitmap(photo);
		}
	}

	private Bitmap addFlagToPhoto(Bitmap contact_photo, Bitmap flag) {

		if (contact_photo != null) {
			Bitmap photo = contact_photo.copy(Config.ARGB_8888, true);

			Canvas canvas = new Canvas(photo);
			Paint paint = new Paint();

			// draw flag in bottom_right corner
			canvas.drawBitmap(flag, photo.getWidth() - flag.getWidth(),
					photo.getHeight() - flag.getHeight(), paint);

			// complete image
			return photo;
		} else {
			return contact_photo;
		}
	}
}